/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.
 */
package es.silenus.detecta.service.impl;

import es.silenus.detecta.dao.OrganizationDAO;

import es.silenus.detecta.model.Organization;

import org.springframework.ldap.core.DirContextOperations;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;


/**
 * LDAP to organization context mapper.
 *
 * @author <a href="mailto:malonso@silenus-consultoria.es">Mariano Alonso</a>
 *
 * @since 26-jun-2009 0:16:31
 */
public class OpenLDAPOrganizationMapper implements LDAPOrganizationMapper {
	/**
	 * The object classes.
	 */
	private List<String> objectClasses;

	/**
	 * The group id.
	 */
	private String groupIdAttribute;

	/**
	 * The group name.
	 */
	private String groupNameAttribute;

	/**
	 * The organization DAO.
	 */
	private OrganizationDAO organizationDAO;

/**
   * Constructor.
   */
	public OpenLDAPOrganizationMapper() {
		// Default values
		objectClasses = new ArrayList<String>();
		objectClasses.add("posixGroup");
		objectClasses.add("top");

		groupIdAttribute = "gidNumber";
		groupNameAttribute = "cn";
	}

	/**
	 * Sets the object classes.
	 *
	 * @param objectClasses the object classes.
	 */
	public void setObjectClasses(final List<String> objectClasses) {
		this.objectClasses = objectClasses;
	}

	/**
	 * Sets the group id attribute.
	 *
	 * @param groupIdAttribute the group id attribute.
	 */
	public void setGroupIdAttribute(final String groupIdAttribute) {
		this.groupIdAttribute = groupIdAttribute;
	}

	/**
	 * Sets the group name attribute.
	 *
	 * @param groupNameAttribute the group name attribute.
	 */
	public void setGroupNameAttribute(final String groupNameAttribute) {
		this.groupNameAttribute = groupNameAttribute;
	}

	/**
	 * Sets the organization DAO.
	 *
	 * @param organizationDAO the organization DAO.
	 */
	public void setOrganizationDAO(OrganizationDAO organizationDAO) {
		this.organizationDAO = organizationDAO;
	}

	/**
	 * Maps a context into an organizational group.
	 *
	 * @param ctx the context.
	 * @param groupName the group name.
	 *
	 * @return the organizational group.
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public Organization mapGroupFromContext(DirContextOperations ctx, String groupName) {
		Organization result = organizationDAO.findByName(groupName);

		if(result == null) {
			result = new Organization();
		}

		/*
		   if(StringUtils.hasLength(groupIdAttribute)) {
		     result.setId((Integer)ctx.getObjectAttribute(groupIdAttribute));
		   }
		 */
		if(StringUtils.hasLength(groupNameAttribute)) {
			result.setName(ctx.getStringAttribute(groupNameAttribute));
		}

		return result;
	}

	/**
	 * Maps an organizational group into a context.
	 *
	 * @param organization the organizational group.
	 * @param ctx the context.
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public void mapGroupToContext(Organization organization, DirContextOperations ctx) {
		if(!ctx.isUpdateMode()) {
			ctx.setAttributeValues("objectClass", objectClasses.toArray());
		}
		if(StringUtils.hasLength(groupIdAttribute)) {
			ctx.setAttributeValue(groupIdAttribute, String.valueOf(organization.getId()));
		}

		if(StringUtils.hasLength(groupNameAttribute)) {
			ctx.setAttributeValue(groupNameAttribute, organization.getName());
		}
	}
}
